﻿using Keysight.Tap;

namespace Nokia.Tap.Driver.Eload
{
    /// <summary>
    ///     This enum is used to set/inform ON- or OFF-states with methods
    /// </summary>
    public enum EState
    {
        [Scpi("OFF")] Off,
        [Scpi("ON")] On
    }

    public enum EErrorOccurred
    {
        No,
        Yes
    }

    public enum EopcStatus
    {
        Incomplete = 0,
        Complete = 1
    }

    public enum ELoadMode
    {
        ConstantCurrent,
        ConstantResistance,
        EloadModeUnknown
    }

    public enum ESlewRateDirection
    {
        Positive,
        Negative
    }

    public enum ELoadParallelInit
    {
        Off,
        On
    }

    public enum ELoadParallelMode
    {
        None,
        Master,
        Slave
    }

    public enum ETriggerSource
    {
        [Scpi("IMM")] Single,
        [Scpi("BUS")] Bus,
        [Scpi("EXT")] External,
        [Scpi("HOLD")] Hold,
        [Scpi("LINE")] Line,
        [Scpi("TIM")] Timer
    }

    public enum ETriggerSequence
    {
        [Scpi("LIST")] List,
        [Scpi("ACQ")] Measurement
    }

    public enum ETransientMode
    {
        [Scpi("CONT")]Continuous,
        [Scpi("PULS")]Pulse,
        [Scpi("TOGG")]Toggle
    }

    public enum ETransientSource
    {
        [Scpi("FIX")] Immediate,
        [Scpi("LIST")] List
    }

    public interface IEload : IInstrument
    {
        /// <summary>
        /// Clears errors from instrument
        /// </summary>
        void Clear();

        /// <summary>
        /// Queries instrument info
        /// </summary>
        /// <returns>Instrument information</returns>
        string Identify();

        /// <summary>
        /// Checks from instrument if previous operation is completed or not.
        /// </summary>
        /// <returns>The operation complete status</returns>
        EopcStatus Opc(); //bool

        /// <summary>
        /// Prohibits the instrument from executing any new commands until all pending
        /// overlapped commands have been completed.
        /// </summary>
        void Wait();

        /// <summary>
        ///    The entire error queue is read, then emptied from instrument
        /// </summary>
        /// <param name="response">Returns the response string</param>
        /// <returns>Gives the error occurred status</returns>
        bool SystemError(out string response);

        /// <summary>
        /// Resets the power supply to a factory-defined state.
        /// </summary>
        void EloadReset();

        /// <summary>
        /// Returns dll version.
        /// </summary>
        /// <returns>The dll version information.</returns>
        string GetVersion();

        /// <summary>
        /// Sets eload current.
        /// <param name="channel">channel number</param>
        /// <param name="currentA">Used current (A).</param>
        /// </summary>
        void SetCurrent(long channel, double currentA);

        /// <summary>
        /// Sets eload resistance.
        /// <param name="channel">channel number</param>
        /// <param name="resistanceOhm">Used resistance (Ohm).</param>
        /// </summary>
        void SetResistance(long channel, double resistanceOhm);

        /// <summary>
        /// Sets eload on or off.
        /// <param name="channel">channel number</param>
        /// <param name="onOff">Eload On or Off.</param>
        /// </summary>
        void ELoadOnOff(long channel, EState onOff);

        /// <summary>
        /// Sets eloads functional mode. Either constant current or constant resistance.
        /// <param name="channel">channel number</param>
        /// <param name="eLoadMode">CC or CR.</param>
        /// <param name="maxValueOfMeasurement">Maximum value of measurement(range),due for selected measurement type (CC= constant current, CR= constant resistance) user should know maximum range of mesurement value</param>
        /// </summary>
        void SetMode(long channel, ELoadMode eLoadMode, double maxValueOfMeasurement);

        /// <summary>
        /// Gets eload functional mode
        /// </summary>
        /// <returns>The Eload mode.</returns>
        ELoadMode GetMode();

        /// <summary>
        /// Sets reading measurement from UUT or LOAD
        /// </summary>
        /// <param name="channel">channel number</param>
        /// <param name="sense">True for UUT else LOAD</param>
        void SetReadFromSense(long channel, bool sense);

        /// <summary>
        /// Sets eloads transient generator to continuous mode and state on or off
        /// </summary>
        /// <param name="channel">channel number</param>
        /// <param name="onOff">Transient gen on or off</param>
        void SetContinuousTransientModeOnOff(long channel, EState onOff);

        /// <summary>
        /// Setups eloads continuous transient settings.
        /// </summary>
        /// <param name="channel">channel number</param>
        /// <param name="mainCurrentA">main level of the input current</param>
        /// <param name="transientCurrentA">transient level of the input current in amps</param>
        /// <param name="frequencyHz">frequency of the transients in hertz</param>
        /// <param name="dutyCyclePercentage">duty cycle of each of the transients in percentage</param>
        void SetupContinuousTransient(long channel, double mainCurrentA, double transientCurrentA, uint frequencyHz,
            uint dutyCyclePercentage);

        /// <summary>
        /// Measure current
        /// <param name="channel">channel number</param>
        /// </summary>
        /// <returns>Eload current, amps(A))</returns>
        double MeasureCurrent(long channel);

        /// <summary>
        /// Measure voltage
        /// <param name="channel">channel number</param>
        /// </summary>
        /// <returns>Eload voltage, volts(V)</returns>
        double MeasureVoltage(long channel);

        /// <summary>
        /// Measure power
        /// <param name="channel">channel number</param>
        /// </summary>
        /// <returns>Eload power,watts(W)</returns>
        double MeasurePower(long channel);

        /// <summary>
        /// Measure maximum voltage
        /// <param name="channel">channel number</param>
        /// </summary>
        /// <returns>Eload maximum voltage, volts(V)</returns>
        double MeasureMaximumVoltage(long channel);

        /// <summary>
        /// Measure minimm voltage
        /// <param name="channel">channel number</param>
        /// </summary>
        /// <returns>Eload minimum voltage, volts(V)</returns>
        double MeasureMinimumVoltage(long channel);

        /// <summary>
        /// Set Channel
        /// <param name="channel">channel number</param>
        /// </summary>
        void SetChannel(long channel);

        /// <summary>
        /// Get channel
        /// </summary>
        /// <returns>channel number</returns>
        long GetChannel();

        /// <summary>
        /// Sets transient current level in amps and also slew rate to max
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="transientCurrent"></param>
        void SetTransientCurrent(long channel, double transientCurrent);

        /// <summary>
        /// Sets continuous transient frequency
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="frequencyHz"></param>
        void SetContinuousTransientFrequency(long channel, uint frequencyHz);

        /// <summary>
        /// Sets continuous transient duty cycle
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="dutyCyclePercentage"></param>
        void SetContinuousTransientDutyCycle(long channel, uint dutyCyclePercentage);

        /// <summary>
        /// Set transient current slew rate
        /// </summary>
        /// <param name="channel">channel number</param>
        /// <param name="slewRateDirect">slew rate direction</param>
        /// <param name="slewRate">slew rate (rang:1e3 ~ 5e6)</param>
        void SetTransientCurrentSlewRate(long channel, ESlewRateDirection slewRateDirect, double slewRate);

        /// <summary>
        /// Set trigger source of the frame
        /// this command is not channel related and applies to entire frame
        /// </summary>
        /// <param name="source"></param>
        void SetTriggerSource(ETriggerSource source);

        /// <summary>
        /// Set trigger timer, value from 8us to 4s
        /// this command is not channel related and applies to entire frame
        /// </summary>
        /// <param name="timerMs"></param>
        void SetTriggerTimer(double timerMs);

        /// <summary>
        ///Set trigger delay of selected channel
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="delayMs"></param>
        void SetTriggerDelay(long channel, uint delayMs);

        /// <summary>
        /// reset trigger system
        /// </summary>
        void ResetTriggerSystem();

        /// <summary>
        /// Initiate trigger list/measurement
        /// </summary>
        /// <param name="triggerSeq"></param>
        void InitiateTriggerSequence(ETriggerSequence triggerSeq);

        /// <summary>
        /// Set continuous initiate trigger status
        /// </summary>
        /// <param name="state"></param>
        void SetContinuousTriggerInitiateOnOff(EState state);

        /// <summary>
        /// Select transient mode
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="mode">Continuous, Pulse, Toggle</param>
        void SelectTransientMode(long channel, ETransientMode mode);

        /// <summary>
        /// Enable/Disable transientMode.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="onOff"></param>
        void SetTransientModeOnOff(long channel, EState onOff);

        /// <summary>
        /// Select whether transient generator uses immediate or list values
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="source"></param>
        void SelectTransientSource(long channel, ETransientSource source);

        /// <summary>
        /// Set the pulse width of the transients when generator is in PULSE mode
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="pulseWidthMs"></param>
        void SetPulseTransientModeWidth(long channel, double pulseWidthMs);

        /// Run manufacturers self-test(*TST?) for instrument.
        /// </summary>
        /// <param name="message"> Message returned from test.</param>
        /// <returns>Result code: 0 = pass / other numbers are error/fails.</returns>
        int Selftest(out string message);

        /// <summary>
        /// Sets parallel initialization.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="onOff"></param>
        void SetParallelInit(long channel, ELoadParallelInit onOff);

        /// <summary>
        /// Sets parallel mode.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="parallelMode"></param>
        void SetParallelMode(long channel, ELoadParallelMode parallelMode);

        /// <summary>
        /// Gets parallel mode.
        /// </summary>
        /// <returns></returns>
        ELoadParallelMode GetParallelMode();
    }
}